using System;
using System.Collections.Generic;
using System.Text;
using My.IdlConverter.Core;
using My.IdlConverter.Core.Util;
using My.IdlConverter.Core.Graphics;

namespace My.IdlConverter.Com
{
    public abstract class ComLibraryTemplate
    {
        private static IDictionary<string, StringBuilder> _librarySegs = new Dictionary<string, StringBuilder>();
        private static IDictionary<string, string> _properties = new Dictionary<string, string>();
        private IList<string> _importLibries = new List<string>();
        private ClassForest _forest;

        //default values
        public static readonly string DefaultCustom = "custom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,\"{7D1B5AE7-0DEE-46F1-89FA-A916EA310C81}\")";
        public static readonly string DefaultLibraryName = Component.Name;
        public static readonly string DefaultVersion = "1.0";

        //library composition,in order
        public static readonly string Header = "header";
        public static readonly string LibraryDeclaration = "LibraryDeclaration";
        public static readonly string ImportLib = "ImportLib";
        public static readonly string Registar = "Registar";
        public static readonly string CoClass = "CoClass";
        public static readonly string Tail = "Tail";

        //properties
        public static readonly string CustomString = "Custom";
        public static readonly string VersionString = "Version";
        public static readonly string LibraryName = "Library";

        static ComLibraryTemplate()
        {
            StringBuilder header = new StringBuilder();
            header.AppendLine("[");
            header.AppendFormat(StringUtil.FormatIndent1("uuid({0}),\n",ComGuidCenter.Apply(Component.Name)));
            header.AppendFormat(StringUtil.FormatIndent1("version({0}),\n",GlobalConst.VersionTemplate));
            header.AppendLine(StringUtil.FormatIndent1("helpstring(\"Type Library\"),"));
            header.AppendFormat(StringUtil.FormatIndent1("{0}\n",GlobalConst.CustomTemplate));
            header.AppendLine("]");

            StringBuilder libraryDeclaration = new StringBuilder();
            libraryDeclaration.AppendFormat("library {0}\n",GlobalConst.LibraryTemplate);
            libraryDeclaration.AppendLine("{");

            StringBuilder importLib = new StringBuilder();

            StringBuilder registar = new StringBuilder();

            StringBuilder coClass = new StringBuilder();

            StringBuilder tail = new StringBuilder();
            tail.AppendLine("}");

            _librarySegs.Add(Header,header);
            _librarySegs.Add(LibraryDeclaration, libraryDeclaration);
            _librarySegs.Add(ImportLib, importLib);
            _librarySegs.Add(Registar,registar);
            _librarySegs.Add(CoClass,coClass);
            _librarySegs.Add(Tail,tail);

            _properties.Add(CustomString, DefaultCustom);
            _properties.Add(VersionString, DefaultVersion);
            _properties.Add(LibraryName, DefaultLibraryName);
        }

        public ComLibraryTemplate()
        {
        }

        public ComLibraryTemplate(ClassForest forest)
        {
            _forest = forest;
        }

        public ClassForest Consumer
        {
            set
            {
                if (value == null)
                    throw new ArgumentNullException("The class forest should not null.");
                _forest = value;
            }
            protected get
            {
                return _forest;
            }
        }

        public IDictionary<string, StringBuilder> Contents
        {
            get
            {
                _librarySegs[Header] = _librarySegs[Header].Replace(GlobalConst.VersionTemplate, Properties[VersionString])
                                   .Replace(GlobalConst.CustomTemplate, Properties[CustomString]);
                _librarySegs[LibraryDeclaration] = _librarySegs[LibraryDeclaration].Replace(GlobalConst.LibraryTemplate, Properties[LibraryName]);

                return _librarySegs;
            }
        }

        public IDictionary<string, string> Properties
        {
            get
            {
                return _properties;
            }
        }

        public IList<string> ImportLibraries
        {
            get
            {
                return _importLibries;
            }
        }

        public IDictionary<string, StringBuilder> DefaultContents
        {
            get
            {
                Reset();

                return Contents;
            }
        }

        public override string ToString()
        {
            return New().ToString();
        }

        public virtual StringBuilder New()
        {
            StringBuilder buffer = new StringBuilder();

            StringUtil.FillBuffer(buffer,Contents[Header]);
            StringUtil.FillBuffer(buffer, Contents[LibraryDeclaration]);
            StringUtil.FillBuffer(buffer, Contents[ImportLib]);
            StringUtil.FillBuffer(buffer, Contents[Registar]);
            StringUtil.FillBuffer(buffer, Contents[CoClass]);
            StringUtil.FillBuffer(buffer, Contents[Tail]);

            Reset();

            return buffer;
        }

        protected virtual void Reset()
        {
            Contents[ImportLib].Remove(0, Contents[ImportLib].Length);
            Contents[Registar].Remove(0, Contents[Registar].Length);
            Contents[CoClass].Remove(0, Contents[CoClass].Length);
        }
    }
}
